package com.webull.information.center.carwler.common.util.aws.s3;

import com.amazonaws.ClientConfiguration;
import com.amazonaws.Protocol;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.regions.Region;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.model.GetObjectRequest;
import com.amazonaws.services.s3.model.ObjectMetadata;
import com.amazonaws.services.s3.model.PutObjectRequest;
import com.amazonaws.services.s3.model.S3Object;
import com.amazonaws.services.s3.transfer.TransferManager;
import com.amazonaws.services.s3.transfer.Upload;
import com.amazonaws.services.s3.transfer.model.UploadResult;
import com.webull.framework.mvc.ApiException;
import com.webull.framework.util.UtilJson;
import com.webull.information.center.carwler.common.util.CarwlerNetWorksUtil;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.ByteArrayInputStream;
import java.util.Map;
import java.util.Optional;

/**
 * @author smj
 * @version jdk1.8
 * @Description
 * @Date 上午10:54:36
 */
@SuppressWarnings("Duplicates")
@Component
public class AwsS3ClientUtil {

    private @Value("${s3_cn_config}")
    String configS3;
    private final String charEncoding = "utf-8";
    Map<String, Object> ssss = null;
    private @Autowired
    CarwlerNetWorksUtil networksIPUtil;

    private Map<String, Object> getS3config() {
        if (ssss != null)
            return ssss;
        Map<String, Object> s3 = UtilJson.toMap(configS3);
        if (s3.isEmpty()) {
            throw new ApiException("S3配置为空");
        }
        ssss = s3;
        return ssss;
    }

    private TransferManager transferManager = null;

    private TransferManager genTransferManager() {
        if (transferManager != null)
            return transferManager;
        synchronized (this) {
            if (transferManager == null) {
                transferManager = new TransferManager(genAmazonS3());
            }
        }
        return transferManager;
    }

    private AmazonS3Client genAmazonS3() {

        Map<String, Object> s3 = getS3config();
        BasicAWSCredentials awsCreds = new BasicAWSCredentials((String) s3.get("accessKey"),
                (String) s3.get("secretKey"));
        ClientConfiguration clientConfig = new ClientConfiguration();
        clientConfig.setProtocol(Protocol.HTTP);

        // 代理模式与美国S3的相反
        Optional.ofNullable(networksIPUtil.isProxyOpen(false) ?
                networksIPUtil.getWallProxyServiceHttp() : null)
                .ifPresent(p -> {
                    clientConfig.setProxyHost(p.getAdress());
                    clientConfig.setProxyPort(p.getPort());
                });

        AmazonS3Client s3Client = new AmazonS3Client(awsCreds, clientConfig);
        Region region = Region.getRegion(Regions.fromName(Regions.CN_NORTH_1.getName()));
        final String serviceEndpoint = region.getServiceEndpoint(AmazonS3Client.S3_SERVICE_NAME);
        s3Client.setEndpoint(serviceEndpoint);
        return s3Client;

    }

    public boolean uploadNewsHtml(String key, String content) throws Exception {
        String bucketKey = "web_site";
        return uploadHtml(key, content, bucketKey);
    }

    public boolean uploadNewsPicture(String key, byte[] content) throws Exception {
        String bucketKey = "web_site";
        return uploadPicture(key, content, bucketKey);
    }

    /**
     * @param key
     * @param content
     * @param bucketKey :s3_bucket
     * @throws Exception
     * @since 0.1.0
     */
    public boolean uploadHtml(String key, String content, String bucketKey) throws Exception {
        Map<?, ?> s3 = getS3config();
        TransferManager transferManager = null;
        try {
            transferManager = genTransferManager();
            byte[] bytes = content.getBytes(charEncoding);
            ObjectMetadata metadata = new ObjectMetadata();
            // metadata.setContentEncoding(charEncoding);

            metadata.setContentLength(bytes.length);// web_site222
            metadata.setContentType("text/html;charset=UTF-8");
            PutObjectRequest upload = new PutObjectRequest((String) s3.get(bucketKey), key,
                    new ByteArrayInputStream(bytes), metadata);
            Upload resp = transferManager.upload(upload);
            UploadResult loadResult = resp.waitForUploadResult();
            return StringUtils.isNotEmpty(loadResult.getETag());
        } finally {
            // if (transferManager != null) {
            // transferManager.shutdownNow();
            // }
        }
    }

    public boolean uploadPicture(String key, byte[] bytes, String bucketKey) throws Exception {
        Map<?, ?> s3 = getS3config();
        TransferManager transferManager = null;
        try {
            transferManager = genTransferManager();
            ObjectMetadata metadata = new ObjectMetadata();

            metadata.setContentLength(bytes.length);// web_site222
            metadata.setContentType("image/jpeg");
            PutObjectRequest upload = new PutObjectRequest((String) s3.get(bucketKey), key,
                    new ByteArrayInputStream(bytes), metadata);
            Upload resp = transferManager.upload(upload);
            UploadResult loadResult = resp.waitForUploadResult();
            return StringUtils.isNotEmpty(loadResult.getETag());
        } finally {
            // if (transferManager != null) {
            // transferManager.shutdownNow();
            // }
        }
    }

    /**
     * @param key
     * @return
     * @throws Exception
     */
    public S3WullObject downloadNewsFile(String key) throws Exception {
        Map<?, ?> s3 = getS3config();
        String bucketName = (String) s3.get("web_site");
        return downloadS3File(key, bucketName);
    }

    public S3WullObject downloadS3File(String key, String bucketName) throws Exception {

        AmazonS3 amazonS3 = null;
        try {
            S3WullObject sWullObject = new S3WullObject();
            amazonS3 = genAmazonS3();
            GetObjectRequest getObjectRequest = new GetObjectRequest(bucketName, key);
            S3Object s3Object = amazonS3.getObject(getObjectRequest);

            // 把inputStrem离线处理.否则collection关闭后取不到流
            sWullObject.setObjectMetadata(s3Object.getObjectMetadata());
            sWullObject.setObjectContent(new ByteArrayInputStream(IOUtils.toByteArray(s3Object.getObjectContent())));
            return sWullObject;
        } finally {
            // if (amazonS3 != null && amazonS3 instanceof AmazonS3Client) {
            // ((AmazonS3Client) amazonS3).shutdown();
            // }
        }
    }
}
